﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;

namespace PersonaLibrary.Data
{
	public partial class Employee
	{
		private EventsEntitySet<EmployeeNoteLink> _lazyNotes;
		private EventsEntitySet<ConnectionJobEmplDep> _lazyConnections;
		private bool _canLazyNotesLoad;
		private bool _canLazyConnectionsLoad;
		private bool? _conflict;
		
		private string _notes;
		
		private void TryInitDefaultValues()
		{
			if (string.IsNullOrEmpty(DefaultAddress))
			{
				if (ConnectionJobEmplDeps.Count == 0 && !string.IsNullOrEmpty(PersonalAdress))
					DefaultAddress = PersonalAdress;

				if (ConnectionJobEmplDeps.Count == 1 && (string.IsNullOrEmpty(ConnectionJobEmplDeps[0].Department.Address) && !string.IsNullOrEmpty(PersonalAdress)))
					DefaultAddress = PersonalAdress;

				if (ConnectionJobEmplDeps.Count == 1 && string.IsNullOrEmpty(PersonalAdress))
					DefaultAddress = ConnectionJobEmplDeps[0].Department.Address;
			}

			if (string.IsNullOrEmpty(DefaultPhone))
			{
				if (ConnectionJobEmplDeps.Count == 0 && !string.IsNullOrEmpty(PersonalPhone))
					DefaultPhone = PersonalPhone;

				if (ConnectionJobEmplDeps.Count == 1 && (string.IsNullOrEmpty(ConnectionJobEmplDeps[0].Department.Telephone)  && !string.IsNullOrEmpty(PersonalPhone)))
					DefaultPhone = PersonalPhone;

				if (ConnectionJobEmplDeps.Count == 1 && string.IsNullOrEmpty(PersonalPhone))
					DefaultPhone = ConnectionJobEmplDeps[0].Department.Telephone;
			}

			if(string.IsNullOrEmpty(DefaultOrganization))
			{
				if (ConnectionJobEmplDeps.Count == 1)
					DefaultOrganization = ConnectionJobEmplDeps[0].Department.Organization.ToString();

				if(ConnectionJobEmplDeps.Count > 1)
				{
					if (ConnectionJobEmplDeps.All(x => x.Department.OrganizationId == ConnectionJobEmplDeps[0].Department.OrganizationId))
						DefaultOrganization = ConnectionJobEmplDeps[0].Department.Organization.ToString();
				}
			}
		}

		public object MaxOrganizationRank
		{
			get
			{
				if (ConnectionJobEmplDeps != null)
				{
					var selectResult = ConnectionJobEmplDeps.Where(x => x.Department.Organization.Priority.HasValue).ToList();
					if (selectResult.Count == 0)
						return 0;

					return selectResult.Max(x => x.Department.Organization.Priority.Value);
				}

				return null;
			}
		}

		public bool IsConflict
		{
			get
			{
				if (!_conflict.HasValue)
				{
					TryInitDefaultValues();
					if ((ConnectionJobEmplDeps.Count >= 1 && !string.IsNullOrEmpty(PersonalAdress)) || (ConnectionJobEmplDeps.Count >= 1 && !string.IsNullOrEmpty(PersonalPhone))
						|| ConnectionJobEmplDeps.Count > 1)
						_conflict = true;
					else
						_conflict = false;
				}
				return _conflict.Value;
			}
		}

		public string MultiBirthday
		{
			get
			{
				if (Birthday.HasValue)
					return Birthday.Value.ToShortDateString();

				return InexactBirthday;
			}
		}

		public string Organization
		{
			get
			{
				if(ConnectionJobEmplDeps != null)
				{
					if(ConnectionJobEmplDeps.Count > 0)
					{
						return ConnectionJobEmplDeps[0].Department.Organization.Name;
					}
				}

				return null;
			}
		}
		
		public string JobName
		{
			get
			{
				if (ConnectionJobEmplDeps != null)
				{
					if (ConnectionJobEmplDeps.Count > 0)
					{
						if (ConnectionJobEmplDeps[0].Job != null)
							return ConnectionJobEmplDeps[0].Job.Name;
					}
				}

				return null;
			}
		}

		public string Notes
		{
			get { return _notes; }
		}

		public override void LoadPartialFields()
		{
			StringBuilder result = new StringBuilder();

			if (EmployeeNoteLinks != null)
			{
				foreach (EmployeeNoteLink employeeNoteLink in EmployeeNoteLinks)
				{
					result.Append(employeeNoteLink.Note);
					result.Append(", ");
				}
			}

			SendPropertyChanged("Notes");
				
			_notes = result.ToString();
		}

		public EventsEntitySet<EmployeeNoteLink> LazyNotes
		{
			get
			{
				if (_lazyNotes == null && _canLazyNotesLoad)
				{
					_lazyNotes = new EventsEntitySet<EmployeeNoteLink>(EmployeeNoteLinks)
									{
										EntityAddedFilter = x => x.EmployeeId == Id
									};
				}
				return _lazyNotes;
			}
		}

		public EventsEntitySet<ConnectionJobEmplDep> LazyConnections
		{
			get
			{
				if (_lazyConnections == null && _canLazyConnectionsLoad)
				{
					_lazyConnections = new EventsEntitySet<ConnectionJobEmplDep>(ConnectionJobEmplDeps)
					{
						EntityAddedFilter = x => x.EmployeeId == Id
					};
				}
				return _lazyConnections;
			}
		}

		public List<KeyValuePair<string, string>> GetAllAvailablePhones()
		{
			List<KeyValuePair<string, string>> result = new List<KeyValuePair<string, string>>();

			if(!string.IsNullOrEmpty(PersonalPhone))
				result.Add(new KeyValuePair<string, string>( "Личный телефон", PersonalPhone ));

			string departmentPhone = "";
			string organizationPhone = "";

			foreach (ConnectionJobEmplDep connection in ConnectionJobEmplDeps)
			{
				string organization = connection.Department.Organization.ToString();

				if (!string.IsNullOrEmpty(connection.Department.Telephone) && departmentPhone != connection.Department.Telephone)
				{
					departmentPhone = connection.Department.Telephone;

					result.Add(new KeyValuePair<string, string>(organization, departmentPhone));
				}

				if (!string.IsNullOrEmpty(connection.Department.Organization.Legalphone) && organizationPhone != connection.Department.Organization.Legalphone)
				{
					organizationPhone = connection.Department.Organization.Legalphone;

					if (departmentPhone != organizationPhone && result.All(x => x.Value != organizationPhone))
						result.Add(new KeyValuePair<string, string>(organization, organizationPhone));
				}

			}

			return result;
		}

		public List<KeyValuePair<string, string>> GetAllAvailableAddress()
		{
			List<KeyValuePair<string, string>> result = new List<KeyValuePair<string, string>>();

			if(!string.IsNullOrEmpty(PersonalAdress))
				result.Add(new KeyValuePair<string, string>("Личный адрес", PersonalAdress));

			string departmentAddress = "";
			string organizationAddress = "";

			foreach (ConnectionJobEmplDep connection in ConnectionJobEmplDeps)
			{
				string organization = connection.Department.Organization.ToString();

				if ( !string.IsNullOrEmpty(connection.Department.Address) && departmentAddress != connection.Department.Address)
				{
					departmentAddress = connection.Department.Address;

					result.Add(new KeyValuePair<string, string>(organization, departmentAddress));
				}

				if ( !string.IsNullOrEmpty(connection.Department.Organization.Legaladdress) && organizationAddress != connection.Department.Organization.Legaladdress )
				{
					organizationAddress = connection.Department.Organization.Legaladdress;

					if (departmentAddress != organizationAddress && result.All(x => x.Value != organizationAddress))
						result.Add(new KeyValuePair<string, string>(organization, organizationAddress));
				}
				
			}

			return result;
		}

		public void LoadConnections()
		{
			_canLazyConnectionsLoad = true;
			SendPropertyChanged("LazyConnections");
		}

		public void LoadNotes()
		{
			_canLazyNotesLoad = true;
			SendPropertyChanged("LazyNotes");
		}

		public override void Detach()
		{
			ConnectionJobEmplDeps = default(System.Data.Linq.EntitySet<ConnectionJobEmplDep>);
			EmployeeNoteLinks = default(System.Data.Linq.EntitySet<EmployeeNoteLink>);
			_Sex1 = default(System.Data.Linq.EntityRef<Sex>);
			base.Detach();
		}
		public override string ToString()
		{
			if (!string.IsNullOrEmpty(Patronymic))
				return string.Concat(Surname, " ", Name, " ", Patronymic);
			if(!string.IsNullOrEmpty(Surname)) 
				return string.Concat(Surname, " ", Name);
			return Name;
		}
	}
}
